﻿#pragma once

#include <iostream>
#include <vector>
#include "Common.h"
using namespace std;

template<class T>
class ObjectPool
{
public:
	ObjectPool()
		:_memory(nullptr)
		, _freelist(nullptr)
		, _leftbytes(0)
	{
	}

	T* New()	//方法 向对象池申请一个 T 类型的对象，并返回这个对象的指针。
	{
		T* obj = nullptr;	//申请的小内存对象				

		if (_freelist)		//自由链表部为空
		{
			obj = (T*)_freelist;	//自由链表头部重当小内存
			_freelist = *(void**)_freelist;
		}
		else
		{
			if (_leftbytes < sizeof(T))	//大块内存中剩余空间都小于要申请的小内存了
			{
				_leftbytes = 128 * 1024;
				_memory = (char*)SystemAlloc(_leftbytes >> 13);//申请大块内存
				if (_memory == nullptr)
				{
					throw bad_alloc();
				}
			}
			obj = (T*)_memory;		//从大块内存中拿到小内存			
			size_t SizeObj = sizeof(T) < sizeof(void*) ? sizeof(void*) : sizeof(T);
			_memory += SizeObj;		//指向大块内存的指针移动			
			_leftbytes -= SizeObj;
		}
		new (obj)T;	//定位new，统一构造不要开空间就构造效率太低
		return obj;
	}
	void Delete(T* obj)	//把用过的内存连接到自由链表
	{
		obj->~T();
		*(void**)obj = _freelist;	//头插
		_freelist = obj;
	}
private:
	char* _memory=nullptr;		//指向大块内存的指针
	void* _freelist=nullptr;	//自由链表 连接那些用完的内存对象
	int _leftbytes=0;		//大块内存中剩余空间的大小
};

